
import os
import time
import re


from playwright.sync_api import Playwright, sync_playwright

from font import FontConvert

from scrapy.selector import Selector

from db import MovieList, MovieInfo as MovieInfoOrm


class MovieInfo:
    def __init__(self,browser,movie_id) -> None:
        self.browswer = browser
        self.movie_id = movie_id
        self.dir = os.path.dirname(__file__)
        self.page = None
        self.body = None
        self.woff_name_arr = []
        self.woff_dict = {}
        pass
    
    def get_info(self):
        self.page = self.browswer.new_page()
        url = f'https://www.maoyan.com/films/{self.movie_id}'
        self.page.on("response",self.handle_response)
        self.page.goto(url)
        self.page.wait_for_load_state('networkidle')
        while len(self.woff_name_arr)==0 or not self.body:
            time.sleep(1)
        self.init_dict()
        info = self.parse_info()
        self.page.close()
        return info
        
    def parse_info(self):
        prefix = 'a1b2c3d4'
        body = str(self.body).replace('&#x',prefix)
        selector = Selector(text = body)
        box_num_raw = selector.css('.movie-index-content.box .stonefont::text').get()
        box_num = self.convert_num(box_num_raw,prefix)
        box_unit = self.convert_hex( selector.css('.movie-index-content.box .unit::text').get())
        
        score_num_raw = selector.css('.index-right span::text').get()
        score_num = self.convert_hex( self.convert_num(score_num_raw,prefix))
        
        return {
            "box_num":box_num,
            "box_unit":box_unit,
            "score_num":score_num
        }
    
    def convert_hex(self,target_str):
        # \\xe4\\xb8\\x87
        matches = re.findall(r'(?:\\x[0-9a-zA-Z]{2})+',target_str)
        for match in matches:
            target_str = target_str.replace(match,bytes.fromhex(match.replace('\\x','')).decode('utf-8'))
        return target_str
    
    def convert_num(self,target_str,prefix):
        # a1b2c3d4 efda
        def transform(match):
            key = match.group(1)
            res = self.woff_dict.get('uni'+key.upper())
            return res
        pattern = prefix+'(.*?);'
        result = re.sub(pattern,transform,target_str)
        return result
    
    def init_dict(self):
        for woff_name in self.woff_name_arr:
            fontConvert = FontConvert(woff_name)
            self.woff_dict =  {**self.woff_dict,**fontConvert.get_dict()} 
    
    
    def handle_response(self,response):
        #woff 写入文件
        if response.request.url.endswith('.woff'):
            response_body = response.body()
            woff_name = str(self.movie_id)+'_'+ response.request.url.split('/')[-1]
            if woff_name not in self.woff_name_arr:
                self.woff_name_arr.append(woff_name)
            with open(os.path.join(self.dir,woff_name),'wb') as f:
                f.write(response_body)
        elif '/ajax/films' in response.request.url:
            self.body = response.body()


def main():
    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=False, args=["--disable-blink-features=AutomationControlled"])
        while True:
            query = """
            select * from movie_list ml left join movie_info mi 
            on ml.movie_id = mi.movie_id where mi.id is null 
            order by ml.id limit 20
            """
            movie_obj_list = MovieList.raw(query)
            if len(movie_obj_list)==0:
                break
            for movie_obj in movie_obj_list:
                movie_id = movie_obj.movie_id
                movieInfo = MovieInfo(browser,movie_id)
                info = movieInfo.get_info()
                info['movie_id'] = movie_id
                MovieInfoOrm.insert(info).execute()
                print(info)

if __name__=='__main__':
    main()